
public class ReplaceableTree<T> extends Tree<T> {

    /**
     * is able to insert subclasses of the node-type
     * for example insert a student even when its a person tree
     * also takes care of ordering
     * @param node
     */
    public void replace(Iter<Boolean> position, Tree<? extends T> t){

        Node<T> currentEl = this.root;
        while(position.hasNext()){
            boolean direction = position.next();
            if(direction == false){ // go left
                currentEl = currentEl.getLeftChild();
            }else{ // go right
                currentEl = currentEl.getRightChild();
            }
        }
        // currentEl does now contain the element that shall be replaced
        
        // we do not want to replace anything if the replaced element does not have a parent, i.e. if it is root
        if(currentEl != this.root){
            ReplaceableTree<T> newTree = new ReplaceableTree<T>();
            TreeIter<? extends T> it = t.iterator();
            while(it.hasNext()){
                newTree.add(it.next());
            }
            // set parent of new node
            newTree.root.setParent(currentEl);
            // set new nodes parents child
            if(currentEl.getParent().getLeftChild() == currentEl){
                currentEl.getParent().setLeftChild(newTree.root);
            }else{
                currentEl.getParent().setRightChild(newTree.root);
            }
            
        }
    }
    
    @Override
    /**
     * inserts a node closest possible to the root
     */
    public void add(T value) {
        
        if(root == null){
            root = new Node<T>(value, null, null, null);
            return;
        }
        
        
        Queue<Node<T>> queue = new Queue<Node<T>>();
        queue.push(this.root);
        Node<T> element = null;
        while (!queue.isEmpty()) {
            element = queue.pop();
            if (element.getLeftChild() == null) {
                element.setLeftChild(new Node<T>(value, element, null, null));
                //new ReplaceableTree_old(element, null, null, node);
                return;
            } else {
                queue.push(element.getLeftChild());
            }
            if (element.getRightChild() == null) {
                element.setRightChild(new Node<T>(value, element, null, null));
                //= new ReplaceableTree_old(element, null, null, value);
                return;
            } else {
                queue.push(element.getRightChild());
            }
        }
    }

    @Override
    public TreeIter<T> iterator() {
        return new TreeIterator<T>(this);
    }
}
